package com.suredy.app.porject.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.transaction.Transactional;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Service;

import com.suredy.app.porject.constants.BidStatus;
import com.suredy.app.porject.model.Bid;
import com.suredy.core.service.BaseSrvWithEntity;

@Service
public class BidSrv extends BaseSrvWithEntity<Bid> {

	@Override
	public DetachedCriteria getDc(Bid t) {
		DetachedCriteria dc = super.getDc(t);

		if (t == null)
			return dc;

		if (!StringUtils.isBlank(t.getId())) {
			dc.add(Restrictions.eq("id", t.getId()));
		}
		if (!StringUtils.isBlank(t.getName())) {
			dc.add(Restrictions.like("name", t.getName(), MatchMode.ANYWHERE));
		}
		if (!StringUtils.isBlank(t.getProjectNo())) {
			dc.add(Restrictions.like("projectNo", t.getProjectNo(), MatchMode.ANYWHERE));
		}
		if (!StringUtils.isBlank(t.getBidNo())) {
			dc.add(Restrictions.like("bidNo", t.getBidNo(), MatchMode.ANYWHERE));
		}
		if (!StringUtils.isBlank(t.getExecutor())) {
			dc.add(Restrictions.like("executor", t.getExecutor(), MatchMode.ANYWHERE));
		}
		if (!StringUtils.isBlank(t.getBidType())) {
			dc.add(Restrictions.eq("bidType", t.getBidType()));
		}
		if (!StringUtils.isBlank(t.getBidWay())) {
			dc.add(Restrictions.eq("bidWay", t.getBidWay()));
		}
		if (t.getStatus() != null) {
			dc.add(Restrictions.eq("status", t.getStatus()));
		}
		if (t.getBiddingerInfo() != null && t.getBiddingerInfo().getBiddinger() != null) {
			dc.add(Restrictions.eq("biddingerInfo.biddinger", t.getBiddingerInfo().getBiddinger()));
		}
		if (t.getBidAgencyInfo() != null && t.getBidAgencyInfo().getAgency() != null) {
			dc.add(Restrictions.eq("bidAgencyInfo.agency", t.getBidAgencyInfo().getAgency()));
		}
		if (t.getFlowStatus() != null) {
			dc.add(Restrictions.eq("flowStatus", t.getFlowStatus()));
		}
		if (t.getOpeningTimeStart() != null) {
			dc.add(Restrictions.ge("openingTime", t.getOpeningTimeStart()));
		}
		if (t.getOpeningTimeEnd() != null) {
			dc.add(Restrictions.lt("openingTime", t.getOpeningTimeEnd()));
		}

		return dc;
	}

	@SuppressWarnings("unchecked")
	public Map<String, Long> getBidStatusTotal(Date yearStart, Date yearEnd) {
		String ql = "SELECT T.status, COUNT(T.id) FROM Bid T {year} GROUP BY T.status";

		List<Object> param = new ArrayList<Object>();

		String yearStr = "";

		if (yearStart != null) {
			yearStr = "signDate >= ?";
			param.add(yearStart);
		}
		if (yearEnd != null) {
			if (!StringUtils.isBlank(yearStr))
				yearStr += " AND";

			yearStr += " signDate <= ?";
			param.add(yearEnd);
		}
		if (StringUtils.isBlank(yearStr)) {
			ql = ql.replace("{year}", "");
		} else {
			ql = ql.replace("{year}", " WHERE " + yearStr);
		}

		List<Object[]> data = null;
		if (param.isEmpty())
			data = (List<Object[]>) this.readByQL(ql);
		else
			data = (List<Object[]>) this.readByQL(ql, param.toArray());

		Map<String, Long> ret = new LinkedHashMap<String, Long>();
		ret.put("投标中", 0L);
		ret.put("中标", 0L);
		ret.put("未中标", 0L);

		if (data != null)
			for (Object[] d : data) {
				if (d == null || d.length != 2)
					continue;

				BidStatus status = (BidStatus) d[0];
				long count = (long) d[1];

				String key = "中标";

				switch (status) {
					case B0001_IN_BIDDING:
					case B0002_MISS_REBID:
						// 投标中
						key = "投标中";
						break;
					case B0004_LOSE:
						// 未中标
						key = "未中标";
						break;
				}

				ret.put(key, ret.get(key) + count);
			}

		return ret;
	}

	@Transactional
	public int deleteByIds(String[] ids) {
		if (ids == null || ids.length <= 0)
			return 0;

		int ret = 0;

		for (String id : ids) {
			Bid bid = this.get(id);

			if (bid == null)
				continue;

			this.delete(bid);

			ret++;
		}

		return ret;
	}

}
